home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / batchut / ask3.zip / ASK3.C < prev    next >
C/C++ Source or Header  |  1986-12-11  |  15KB  |  622 lines

  1. /* Copyright 1986 Academic Computing Center, University of Wisconsin - Madison
  2. **
  3. ** ASK to prompt the user to enter a character. Result is a value 0-255
  4. ** testable in a batch file with the "if errorlevel" construct.
  5. ** Compile with /ze/ox options.
  6. **
  7. ** Written by Peter Wu for the Faculty Support Center.
  8. */
  9.  
  10. #define LINT_ARGS
  11. #define SWITCHC '/'
  12. #define SPECIAL '\\'     /* the escape character */
  13. #define CONTROL '~'      /* control character prefix */
  14. #define XOPN '('         /* open quote for extended ascii e.g. ~(home) */
  15. #define XCLS ')'
  16.  
  17. #define acc(seg,off) ((long)(seg)<<16|(unsigned short)(off))
  18. #define peekb(seg,off) (*(unsigned char far *)acc(seg,off))
  19.  
  20. #include <stdio.h>
  21. #include <conio.h>
  22. #include <ctype.h>
  23. #include <string.h>
  24. #include <time.h>
  25. #include <signal.h>
  26. #include <stdlib.h>
  27. #include <dos.h>
  28. #include <memory.h>
  29.  
  30. char
  31.   *xasc[] = {  /* mnemonics for extended ascii */
  32.     "", "", "", "NULL?", "", "", "", "", "", "", "", "", "", "", "",
  33.     "S-Tab", "A-Q", "A-W", "A-E", "A-R", "A-T", "A-Y", "A-U", "A-I", "A-O",
  34.     "A-P", "", "", "", "", "A-A", "A-S", "A-D", "A-F", "A-G", "A-H", "A-J",
  35.     "A-K", "A-L", "", "", "", "", "", "A-Z", "A-X", "A-C", "A-V", "A-B",
  36.     "A-N", "A-M", "", "", "", "", "", "", "", "", "F1", "F2", "F3", "F4",
  37.     "F5", "F6", "F7", "F8", "F9", "F10", "", "", "Home", "Up", "PgUp", "",
  38.     "Left", "", "Right",
  39.     "", "End", "Down", "PgDn", "Ins", "Del", "S-F1", "S-F2", "S-F3",
  40.     "S-F4", "S-F5", "S-F6", "S-F7", "S-F8", "S-F9", "S-F10", "C-F1", "C-F2",
  41.     "C-F3", "C-F4", "C-F5", "C-F6", "C-F7", "C-F8", "C-F9", "C-F10", "A-F1",
  42.     "A-F2", "A-F3", "A-F4", "A-F5", "A-F6", "A-F7", "A-F8", "A-F9", "A-F10",
  43.     "C-PrtSc", "C-Left", "C-Right", "C-End", "C-PgDn", "C-Home", "A-1", "A-2",
  44.     "A-3",
  45.     "A-4", "A-5", "A-6", "A-7", "A-8", "A-9", "A-0", "A--", "A-=", "C-PgUp"
  46.   };
  47.  
  48. char *xi();
  49. char *xget();
  50. int ctrlc();
  51.  
  52. _setenvp(){}  /* diable code dealing with enironment variables */
  53.  
  54. _nullcheck()  /* disable null pointer checking */
  55. {
  56.   return 0;  /* this line is required */
  57. }
  58.  
  59. main()
  60. {
  61.   char
  62.     argvbuf[128],  /* string space for storing parameter */
  63.     *argv[65],       /* max # of parameters that fits on a line */
  64.     *prompt,       /* prompt string */
  65.     *option,       /* option string */
  66.     *tmp,
  67.     *nulls = "";
  68.  
  69.   int
  70.     argc,
  71.     optf,  /* 0 = no user options on cmd line; 1 = yes */
  72.     quiet,  /* 0 = enable error message; 1 = quiet */
  73.     flead,  /* flush type ahead flag 1=flush */
  74.     echo,
  75.     index,
  76.     timeout,  /* timeout value in seconds */
  77.     timeflag,  /* whether timeout options is set or not */
  78.     where,
  79.     i,
  80.     cases;  /* 0 = case non-sensitive; 1 = case sensitive */
  81.  
  82.   unsigned int
  83.     expect[200],  /* expected response string */
  84.     c;
  85.  
  86.   long
  87.     expire;  /* expire time = start time + timeout */
  88.  
  89.   getarg(&argc, argv, argvbuf);  /* my routine to do argc, argv */
  90.  
  91.   if (argc == 1) {  /* no argument */
  92.     cputs("ASK version 3.0 (Nov 21, 1986) pre-release\15\n\n");
  93.     cputs("Usage: ASK[/cefmqs] [prompt] [expected response]\15\n");
  94.     cputs("/c - case sensitive         /m### - timeout in ### minutes\15\n");
  95.     cputs("/e - no echo                /q - accept unexpected key\15\n");
  96.     cputs("/f - flush type-ahead       /s### - timeout in ### seconds\15\n");
  97.     cputs("E.G. (in batch file):\15\n");
  98.     cputs("  ASK \"Yes or No? \" yn\15\n");
  99.     cputs("  if errorlevel 2 goto NO\15\n");
  100.     exit(0);
  101.   }
  102.  
  103.   /* set default options */
  104.   quiet = 0;  /* not quiet; i.e. beeps on unexpected input */
  105.   cases = 0;  /* not case sensitive; i.e. a == A */
  106.   echo = 1;  /* echo input */
  107.   flead = 0;  /* no flush type-ahead, user can type ahead if he wants */
  108.   timeout = -1;  /* default timeout is immediate */
  109.   timeflag = 0;  /* timeout option not enabled */
  110.  
  111.   if (*argv[1] == SWITCHC) {  /* check for option string */
  112.  
  113.     option = argv[1] + 1;
  114.     optf = 1;  /* remember to shift prompt and expect */
  115.  
  116.     c = *option;
  117.     while (c) {
  118.  
  119.       option++;
  120.       switch (c) {
  121.  
  122.     case SWITCHC: case ' ':
  123.       break;  /* ignore extra switch char and space */
  124.  
  125.     case 'c': case 'C':
  126.       cases = 1;  /* set case sensitive */
  127.       break;
  128.  
  129.     case 'e': case 'E':  /* no echo option */
  130.       echo = 0;
  131.       break;
  132.  
  133.     case 'f': case 'F':  /* flush type ahead */
  134.       flead = 1;  /* the actual flushing is done below */
  135.       break;
  136.  
  137.     case 's':  case 'S':  /* timeout in seconds */
  138.       tmp = xi(option, &i);  /* read timeout value (in seconds) */
  139.       if (tmp > option) {  /* good, user supplied timeout value */
  140.         option = tmp;
  141.         if (timeflag) {  /* not the first timeout option */
  142.           timeout += i;  /* accumulate this timeout value */
  143.         } else {  /* first timeout option */
  144.           timeout = i;
  145.         }
  146.       }  /* if no timeout value is supplied, ignore it */
  147.       timeflag = 1;  /* enable timeout input */
  148.       break;
  149.  
  150.     case 'm':  case 'M':  /* timeout in minutes */
  151.       tmp = xi(option, &i);  /* read timeout value (in seconds) */
  152.       if (tmp > option) {  /* good, user supplied timeout value */
  153.         option = tmp;
  154.         if (timeflag) {  /* not the first timeout option */
  155.           timeout += i * 60;  /* convert minutes to seconds */
  156.         } else {  /* first timeout option */
  157.           timeout = i;
  158.         }
  159.       }
  160.       timeflag = 1;
  161.       break;
  162.  
  163.     case 'q': case 'Q':
  164.       quiet = 1;  /* disable error message for unexpected input */
  165.       break;
  166.  
  167.     default:
  168.       cputs("invalid option '"); putch(c); cputs("' ignored\15\n");
  169.       }
  170.       c = *option;
  171.     }  /* while */
  172.  
  173.   } else {  /* argv[1] is not an option string */
  174.  
  175.     optf = 0;
  176.  
  177.   }
  178.  
  179.   /* now figure out which is the prompt string, which is the expected
  180.   ** response string
  181.   */
  182.   if (argc-optf > 2) {    /* expected response string present */
  183.     if (!cases) {
  184.       strupr(argv[2+optf]);  /* convert to upper case if not case sensitive */
  185.     }
  186.     ex(argv[2+optf], expect);
  187.   } else {
  188.     expect[0] = 0;  /* no expected response string */
  189.   }
  190.  
  191.   if (argc-optf > 1) {    /* prompt string present */
  192.     prompt = argv[1+optf];
  193.   } else {
  194.     prompt = "? ";  /* default prompt string */
  195.   }
  196.  
  197.   if (!echo) {    /* if no echo then turn off the cursor */
  198.     cursor('s');  /* save cursor mode */
  199.     signal(SIGINT, ctrlc);  /* restore cursor if break key is hit */
  200.     cursor('h');  /* hide cursor */
  201.   }
  202.  
  203.   do {
  204.  
  205.     cputs(prompt);
  206.  
  207.     /* flush type-ahead if so requested */
  208.     if (flead) {
  209.       flush_ahead();
  210.     }
  211.  
  212.     /* process timeout if necessary */
  213.     if (timeflag) {
  214.  
  215.       /* if user selected timeout option without a timeout value, the default
  216.       ** value of -1 will be used. This means timeout immediately, it won't
  217.       ** even read type-ahead's in the keyboard buffers.
  218.       */
  219.       if (timeout < 0) {
  220.     cexit(255, echo);
  221.       }
  222.  
  223.       expire = time(NULL) + timeout;
  224.  
  225.       /* if user select timeout with value 0, the keyboard buffer will be
  226.       ** examined once meaning type-aheads will be read.
  227.       */
  228.       while (!kbhit()) {  /* while keyboard buffer is empty */
  229.     if (time(NULL) >= expire) {  /* timeout! */
  230.       cexit(255, echo);
  231.     }
  232.       }
  233.     }
  234.  
  235.     c = xgetc();  /* read a key from keyboard */
  236.  
  237.     if (echo) {
  238.       xputc(c);  /* echo extended character */
  239.       cputs("\15\n");
  240.     }
  241.  
  242.     if (!cases) {  /* not case sensitive, so convert it to UPPER */
  243.       if (c < 256) {  /* convert only normal ascii */
  244.     c = toupper(c);
  245.       }
  246.     }
  247.  
  248.     /* If no expected string is supplied, then return the character code
  249.     ** of the key (e.g. A returns 65) in errorlevel. If an extended ascii
  250.     ** key is pressed (e.g. [F0]) then this will return 0.
  251.     */
  252.     if (expect[0] == 0) {
  253.       cexit(c, echo);
  254.     }
  255.  
  256.     /* search for c in expected response string */
  257.     where = istrchr(expect, c);
  258.     if (where > -1) {  /* found! */
  259.       cexit(where + 1, echo);
  260.     }
  261.  
  262.     if (!quiet) {
  263.       if (!echo) {
  264.     cputs("\15\n");
  265.       }
  266.       cputs("\7unexpected key, please try again\15\n\n");
  267.     }
  268.  
  269.   } while (!quiet);
  270.  
  271.   cexit(0, echo);  /* means unexpected key press and quiet option set *